<?php

namespace app\admin\controller\work;

use think\App;
use app\Request;
use think\facade\Db;
use think\facade\Log;
use app\common\controller\AdminController;
use app\admin\service\annotation\ControllerAnnotation;
use app\admin\service\annotation\NodeAnnotation;
use app\admin\model\WorkAttendance;
use app\admin\model\WorkAttendanceStatistics;

#[ControllerAnnotation(title: '考勤管理')]
class Attendance extends AdminController
{

    private array $notes;
    protected bool $ignoreLogin = true;
    private array $rule             = [
        'date'   => 'require',
        'state'   => 'require',
        'work_duration'   => 'require',
        'drive'   => 'require',
    ];
    private array $message = [
        'date.require'   => '请选择【出勤日期】',
        'state.require'   => '请选择【出勤状态】',
        'work_duration.require' => '请选择【工时】',
        'drive.require'   => '请选择【是否驾驶】',
    ];
    private array $attendance_state = [
        ['name' => '上班', 'value' => '1'],
        ['name' => '休息', 'value' => '0'],
        ['name' => '请假', 'value' => '-1']
    ];
    private array $work_duration = [
        ['name' => '1个', 'value' => '1', 'id' => 'work_duration_work'],
        ['name' => '0.5个', 'value' => '0.5', 'id' => 'work_duration_rest'],
        ['name' => '无', 'value' => '0', 'id' => 'work_duration_leave']
    ];
    private array $drive = [
        ['name' => '是', 'value' => '1', 'id' => 'drive_yes'],
        ['name' => '否', 'value' => '0', 'id' => 'drive_no']
    ];

    protected array $sort = [
        'date' => 'desc',
    ];
    public function __construct(App $app)
    {
        parent::__construct($app);
        self::$model = new \app\admin\model\WorkAttendance();
        $notes = self::$model::$notes;

        $this->notes = $notes;
        $this->assign(compact('notes'));
    }

    #[NodeAnnotation(title: '添加', auth: false)]
    public function add(Request $request): string
    {
        if ($request->isPost()) {
            $post  = $request->post();
            $this->validate($post, $this->rule, $this->message);
            $input_date = $post['date'];
            $res = $this->attendanceDateExist($input_date);
            if ($res) {
                $this->error("【" . $input_date . "】" . '已存在出勤记录');
            }
            try {
                $post["leave_duration"] = 1 - floatval($post["work_duration"]);
                $save = self::$model::create($post);
            } catch (\Exception $e) {
                var_dump($e);
                $this->error('添加异常');
            }
            if ($save) {
                $month = date("Y-m", strtotime($input_date));
                $this->statistics($month);
                $this->success('添加成功');
            } else {
                $this->error('添加失败');
            }
        }
        $this->assignConfig();
        return $this->fetch();
    }

    #[NodeAnnotation(title: '删除', auth: true)]
    public function delete(Request $request): void
    {
        $this->checkPostRequest();
        $id  = $request->param('id');
        $row = self::$model::whereIn('id', $id)->select();
        $row->isEmpty() && $this->error('数据不存在');
        $date = $row[0]["'date'"];
        try {
            $save = $row->delete();
        } catch (\Exception $e) {
            $this->error('删除异常');
        }

        if ($save) {
            $month = date("Y-m", $date);
            $this->statistics($month);
            $this->success('删除成功');
        } else {
            $this->error('删除失败');
        }
    }

#[NodeAnnotation(title: '编辑', auth: false)]
    public function edit(Request $request, $id = 0): string
    {
        $row = self::$model::find($id);
        empty($row) && $this->error('记录不存在，无法编辑');
        if ($request->isPost()) {
            $post = $request->post();
            $input_date = $post['date'];
            if ($row['date']!= $input_date) {
                $res = $this->attendanceDateExist($input_date);
                if ($res) {
                    $this->error("【" . $input_date . "】" . '已存在出勤记录');
                }
            }
            $this->validate($post, $this->rule, $this->message);
            $row->state = $post['state'];
            $row->work_duration = $post['work_duration'];
            $row->drive = $post['drive'];
            $row->remark = $post['remark'];
            $row->leave_duration = 1 - floatval($post["work_duration"]);
            try {
                $save = $row->save($post);
            }catch (\Exception $e) {
                $this->error('编辑异常');
            }
            if (!empty($save)) {
                $month = date("Y-m", strtotime($row->date));
                $this->statistics($month);
                $this->success('编辑成功');
            }else {
                $this->error('编辑失败');
            }
        }
        $this->assign([
            'row'   => $row,
        ]);
        $this->assignConfig();
        return $this->fetch();
    }

    /**
     * 判断日期是否已经有出勤
     * @access public
     * @param string $date 日期
     */
    public function attendanceDateExist(string $date): bool
    {
        $admin = WorkAttendance::where('date', $date)->find();
        if (!empty($admin)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 保存配置
     * 
     */
    public function assignConfig(): void
    {
        $this->assign([
            'attendance_state' => $this->attendance_state,
            'work_duration' => $this->work_duration,
            'drive' => $this->drive,
        ]);
    }

    /**
     * 统计出勤
     * @access public
     * @param string $date 日期
     */
    function statistics(string $date): void {
        $month = $date;
        $model = WorkAttendanceStatistics::where("statistics_date", $month.'-01')->findOrEmpty();
        if ($model->isEmpty()) {
            $model = new WorkAttendanceStatistics();
        }
        
        $table = "attendance";
        $column = 'date';
        $parameter = "state";
        $res = Db::name($table)->whereMonth($column, $month)->sum('work_duration');
        $model->sum_duration = $res;

        $res = Db::name($table)->whereMonth($column, $month)
            ->where($parameter, 1)->count();
        
        $model->work_days = $res;    

        $res = Db::name($table)->whereMonth($column, $month)
            ->where($parameter, 0)->count();
        $model->rest_days = $res;

        $res = Db::name($table)->whereMonth($column, $month)
            ->where($parameter, -1)->sum('leave_duration');
        Log::write("【".$month . "】月份请假".$res,"notice");
        $model->leave_days = $res;

        $res = Db::name($table)->whereMonth($column, $month)
            ->where('drive', 1)->count();

        $model->drive_days = $res;
        $model->statistics_date = $month.'-01';

        $model->save();
    }
}
